﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Newtonsoft.Json;
using NPMonitor.DataModel;
using NPMonitor.Implementation;

namespace NPMonitor.Web.UserControls
{
    public class JobSaveEventArgs : EventArgs
    {
        public JobSaveEventArgs(JobDefinition job = null, string operation = null, ExecuteResult eResult = null)
        {
            JobDefinition = job;
            Operation = operation;
            ExecuteResult = eResult;
        }

        public JobDefinition JobDefinition { get; set; }
        public String Operation { get; set; }
        public ExecuteResult ExecuteResult { get; set; }
    }

    public partial class JobInfo : System.Web.UI.UserControl
    {
        #region Events

        public delegate void OnSaveHandler(object sender, JobSaveEventArgs e);

        public event OnSaveHandler OnSave;

        #endregion

        #region Properties

        [Browsable(true)]
        public int JobId
        {
            get;
            set;
        }

        private string viewMode = "View";

        [Browsable(true)]
        public string ViewMode
        {
            get { return viewMode; }
            set
            {
                viewMode = value;

                ShowJobInfo(id: JobId, viewMode: viewMode);
            }
        }

        #endregion

        #region Methods

        public void Reset()
        {
            this.lblJobId.Value = String.Empty;
            this.txtJobName.Text = String.Empty;
            this.txtFileName.Text = String.Empty;
            this.txtTypeName.Text = String.Empty;
            this.txtVersion.Text = String.Empty;
            this.txtDesc.Text = String.Empty;
        }

        private void BindScenarioData(int pageIndex)
        {
            int jobId = 0;
            int.TryParse(this.lblJobId.Value, out jobId);

            if (jobId == 0)
            {
                rptJobScenarios.DataSource = new List<Scenario>();
                lblScenariosCount.InnerText = "0";
            }
            else
            {
                int scenarioTotalCount = StoreManager.Current.JobDefinitionStore.GetScenariosTotalCount(jobId);

                IList<Scenario> jobScenarios = StoreManager.Current.JobDefinitionStore.GetScenarios(jobId, pageIndex);

                lblScenariosCount.InnerText = scenarioTotalCount.ToString();
                rptJobScenarios.DataSource = jobScenarios;
            }

            rptJobScenarios.DataBind();
        }

        public void ShowJobInfo(int? id = null, string viewMode = "View")
        {
            DateTime now = DateTime.Now;

            if (id != null)
            {
                this.JobId = id.Value;

                JobDefinition jd = StoreManager.Current.JobDefinitionStore.GetJobDefinitionById(id.Value);

                if (jd != null)
                {
                    lblJobId.Value = (jd.JobId == null) ? "" : jd.JobId.ToString();
                    txtJobName.Text = jd.JobName;
                    txtFileName.Text = jd.FileName;
                    txtDesc.Text = jd.Desc;
                    txtTypeName.Text = jd.TypeName;
                    txtVersion.Text = jd.Version;
                }
            }
            else
            {
                JobId = 0;
            }

            BindScenarioData(0);

            SetViewMode(viewMode);

            if (id != null)
            {
                txtJobName.Enabled = false;
            }

            phPopEdit.Visible = true;
        }

        private void SetViewMode(string viewMode)
        {
            switch (viewMode)
            {
                case "Create":
                case "Edit":
                    this.txtJobName.Enabled = true;
                    this.txtDesc.Enabled = true;

                    this.btnSave.Visible = true;
                    break;
                case "View":
                    this.txtJobName.Enabled = false;
                    this.txtDesc.Enabled = false;

                    this.btnSave.Visible = false;
                    break;
            }
        }

        #endregion

        protected override void OnPreRender(EventArgs e)
        {
            rfvJobName.ErrorMessage = ValidationString.FieldRequired.FormatString("job name");
            cvJobName.ErrorMessage = ValidationString.FieldInvalid.FormatString("job name");
            rfvJobFile.ErrorMessage = ValidationString.FieldRequired.FormatString("job file");
            cvDescription.ErrorMessage = ValidationString.FieldLengthExceeded.FormatString("Description", 1000);
            rfvScenarioNO.ErrorMessage = ValidationString.FieldRequired.FormatString("scenario number");
            cvScenarioNO.ErrorMessage = ValidationString.FieldInvalid.FormatString("scenario number");
            rfvScenarioName.ErrorMessage = ValidationString.FieldRequired.FormatString("scenario name");
            cvScenarioDescription.ErrorMessage = ValidationString.FieldLengthExceeded.FormatString("Description", 1000);
            revBaseTime.ErrorMessage = ValidationString.RequiredPositiveInteger;
            this.Page.Form.DefaultButton = btnSave.UniqueID;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            phPopEdit.Visible = false;
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(txtJobData.Text))
            {
                JobDefinition job = JsonConvert.DeserializeObject<JobDefinition>(txtJobData.Text);
                IList<Scenario> scenarios = JsonConvert.DeserializeObject<List<Scenario>>(txtScenariosData.Text);
                string tmpFileName = txtTempFileName.Text;

                StoreManager.Current.JobDefinitionStore.SaveJobDefinition(job, tmpFileName, scenarios.ToArray());
                txtTempFileName.Text = null;

                if (OnSave != null)
                {
                    JobSaveEventArgs eventArgs = new JobSaveEventArgs(
                        job: job,
                        operation: (String.IsNullOrEmpty(lblJobId.Value) ? "Create" : "Update"));

                    OnSave(this, eventArgs);
                }
            }
        }
    }
}